#include "module_affichage.h"
#include <assert.h>
#include <string.h>
#include <time.h>
#include <SDL/SDL_ttf.h>


        /*  ACCESSEURS */

SDL_Surface* GetEcranAffichage(const IMAGE * images)
{
    assert(images);
    return images->ecran;
}

SDL_Surface* GetEnnemiBouleAffichage(const IMAGE * images)
{
    assert(images);
    return images->ennemiBoule;
}

SDL_Surface* GetEnnemiTombantAffichage(const IMAGE * images)
{
    assert(images);
    return images->ennemiTombant;
}

SDL_Surface* GetEnnemiBouleDeNeigeAffichage(const IMAGE * images)
{
    assert(images);
    return images->ennemiBouleDeNeige;
}

SDL_Surface* GetEnnemiCanonAffichage(const IMAGE * images)
{
    assert(images);
    return images->ennemiCanon;
}

SDL_Surface* GetIronAffichage(const IMAGE * images)
{
    assert(images);
    return images->iron;
}

SDL_Surface* GetMurAffichage(const IMAGE * images)
{
    assert(images);
    return images->mur;
}

SDL_Surface* GetFondAffichage(const IMAGE * images)
{
    assert(images);
    return images->fond;
}

SDL_Surface* GetVapeurAffichage(const IMAGE * images)
{
    assert(images);
    return images->vapeur;
}

SDL_Surface* GetPicsAffichage(const IMAGE * images)
{
    assert(images);
    return images->pics;
}

SDL_Surface* GetEauAffichage(const IMAGE * images)
{
    assert(images);
    return images->eau;
}

SDL_Surface* GetBossAffichage(const IMAGE * images)
{
    assert(images);
    return images->boss;
}




        /*  FONCTIONS CONCERNANT LA STRUCTURE IMAGE */

SDL_Surface * ChargerImage(const char * nomImage)
{
	FILE * f;
	char nomFichier[72];
	strcpy(nomFichier,"Images/");
	strcat(nomFichier,nomImage);
	f=fopen(nomFichier,"r");
	if (f)
	{
		fclose(f);
		return SDL_LoadBMP(nomFichier);
	}
	else
	{
		fprintf(stderr,"Image %s inexistante\n",nomImage);
		exit(EXIT_SUCCESS);
	}
	return SDL_LoadBMP(nomFichier);
}

void InitialiserImage(IMAGE *images, const char fond)
{
	FILE * f;
	char lecture[64],test2[2];
	int testlecture;
	test2[0]=fond;
	test2[1]='\0';

	printf("Chargement du set d'images '%c'...\n", fond);


	f=fopen("sets.txt","r");
	if (f)
	{
		do
		{
			testlecture=fscanf(f,"%64s",lecture);
			if (testlecture != 1)
			{
				fprintf(stderr,"Set d'images '%c' introuvable, abandon\n", fond);
				exit(EXIT_SUCCESS);
			}
		} while (strcmp(test2,lecture));
	
		fscanf(f,"%64s",lecture);
		images->fond = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->iron = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->vapeur = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->mur = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->pics = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->eau = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->ennemiBoule = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->ennemiTombant = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->ennemiBouleDeNeige = ChargerImage(lecture);
	
		fscanf(f,"%64s",lecture);
		images->ennemiCanon = ChargerImage(lecture);
	
		fscanf(f,"%64s\n",lecture);
		images->boss = ChargerImage(lecture);
	
	
		SDL_SetColorKey(images->boss,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->iron,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->eau,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->pics,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->vapeur,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->ennemiBoule,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->ennemiBouleDeNeige,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->ennemiCanon,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->ennemiTombant,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
		SDL_SetColorKey(images->mur,SDL_SRCCOLORKEY,SDL_MapRGB(images->ecran->format,0,255,0));
	
	
		printf("OK\n");
		fclose(f);
	}
	else
	{
		fprintf(stderr,"Impossible d'ouvrir sets.txt\n");
		exit(EXIT_SUCCESS);
	}
}

IMAGE* CreerImage()
{
    IMAGE *im = (IMAGE*) malloc(sizeof(IMAGE));
    assert(im);
    InitialiserEcran(im);
    return im;
}

void FinNiveauImage(IMAGE *images)
{
	assert(images);

	SDL_FreeSurface(images->vapeur);
	SDL_FreeSurface(images->ennemiBoule);
	SDL_FreeSurface(images->ennemiTombant);
	SDL_FreeSurface(images->ennemiBouleDeNeige);
	SDL_FreeSurface(images->ennemiCanon);
	SDL_FreeSurface(images->iron);
	SDL_FreeSurface(images->mur);
	SDL_FreeSurface(images->fond);
	SDL_FreeSurface(images->pics);
	SDL_FreeSurface(images->boss);
	SDL_FreeSurface(images->eau);
}

void InitialiserEcran(IMAGE *images)
{
	images->ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
	assert(images->ecran);
}


		/*	FONCTIONS CONCERNANT LE NIVEAU */

void AfficherNiveauSDL(IMAGE *images, NIVEAU *terrain, const int positionReelIron)
{
    int i,j,positionDebutX,positionFinX,positionFinY,tailleCase,J,cas;
    char tmp;
    SDL_Surface* murAPoser;
    SDL_Rect decoupe;
    decoupe.x = decoupe.y = 0;
    decoupe.w = decoupe.h = 20;

    MettreSurface(images->fond,images->ecran,0,0,NULL);     /*  on pose le fond */

    tailleCase = GetDimensionCaseNiveau(terrain);


    if(positionReelIron < 320)
    {
        cas = 0;
        positionFinX = 32 * tailleCase;
        positionDebutX = 0;
        positionFinY = GetDimYNiveau(terrain) * tailleCase;
    }
    else if(positionReelIron > GetDimXNiveau(terrain)*tailleCase - 16*tailleCase )
    {
        cas = 1;
        positionFinX = GetDimXNiveau(terrain) * tailleCase;
        positionDebutX = positionFinX - (32 * tailleCase);
        positionFinY = GetDimYNiveau(terrain) * tailleCase;
    }
    else
    {
        cas = 2;
        positionDebutX = positionReelIron - (16*tailleCase);
        positionFinX = positionReelIron + (17*tailleCase);
        positionFinY = GetDimYNiveau(terrain) * tailleCase;

        if(ConversionPixelCase(positionFinX,terrain) > GetDimXNiveau(terrain))
        {
            positionFinX = GetDimXNiveau(terrain) * tailleCase;
        }
        if(positionDebutX < 0)
        {
            positionDebutX = 0;
        }
    }

    for(i=0 ; i<positionFinY ; i = i + tailleCase)
    {
        for(j=positionDebutX ; j<positionFinX ; j = j + tailleCase)
        {
            tmp = GetCaseNiveauPixel(terrain,j,i);
            if(tmp != '-')
            {
                switch(tmp)
                {
                    case '#' :
                        murAPoser = images->mur;
                        break;
                    case '^' :
                        murAPoser = images->pics;
                        decoupe.x = 40;
                        break;
                    case '>' :
                        murAPoser = images->pics;
                        decoupe.x = 60;
                        break;
                    case '<' :
                        murAPoser = images->pics;
                        decoupe.x = 20;
                        break;
                    case 'v' :
                        murAPoser = images->pics;
                        break;
                    case '~' :
                        murAPoser = images->eau;
                        decoupe.x = ((SDL_GetTicks()/1000)%5)*20;
                        break;
                    default :
                        murAPoser = NULL;
                    break;
                }

                if(cas==0)
                {
                    J = j;
                }
                else if(cas==1)
                {
                    J = j-positionDebutX;
                }
                else
                {
                    J = j-positionDebutX - (positionReelIron- (ConversionPixelCase(positionReelIron,terrain)*tailleCase));
                }

                MettreSurface(murAPoser,images->ecran,J,i,&decoupe);
            }
            decoupe.x = 0;
        }
    }

}


void AfficherContinue(IMAGE *images)
{
    TTF_Font *police1 = NULL;
    TTF_Font *police2 = NULL;

    SDL_Color couleur1 = {255,255,255};
    SDL_Color couleur2 = {255,0,0};
    SDL_Color couleur3 = {0,255,0};

    SDL_Surface *Continue,*continuer,*mort;

    police1 = TTF_OpenFont("JustAnotherFont.TTF",80);
    police2 = TTF_OpenFont("JustAnotherFont.TTF",40);

    Continue = TTF_RenderText_Solid(police1, "continue", couleur1);
    assert(Continue);
    continuer = TTF_RenderText_Solid(police2, "continuer", couleur3);
    assert(continuer);
    mort = TTF_RenderText_Solid(police2, "mourir", couleur2);
    assert(mort);

    MettreSurface(Continue,GetEcranAffichage(images),100,40,NULL);
    MettreSurface(continuer,GetEcranAffichage(images),360,240,NULL);
    MettreSurface(mort,GetEcranAffichage(images),40,240,NULL);


    SDL_FreeSurface(Continue);
    SDL_FreeSurface(continuer);
    SDL_FreeSurface(mort);

    TTF_CloseFont(police1);
    TTF_CloseFont(police2);
}


		/*	FONCTIONS CONCERNANT IRON */

void AfficherIronSDL(IMAGE *images, JEU *jeu)
{
    int approcheFinNiveau = GetDimXNiveau(GetTerrain(jeu))*GetDimensionCaseNiveau(GetTerrain(jeu)) - 16*GetDimensionCaseNiveau(GetTerrain(jeu));
    int X,Xvapeur,alpha,i,Xvie = 8;
    SDL_Rect decoupe;
    decoupe.x = decoupe.y = 0;
    decoupe.h = 20;
    decoupe.w = 40;

    if(GetXIron(GetIron(jeu)) < 320)
    {
        X = GetXIron(GetIron(jeu));
    }
    else if(GetXIron(GetIron(jeu)) > approcheFinNiveau)
    {
        X = GetXIron(GetIron(jeu))-(approcheFinNiveau-320);
    }
    else
    {
        X = 320;
    }

    if(!GetADroite(GetIron(jeu)))
    {
        decoupe.y = 20;
    }

    if(GetVitesseXIron(GetIron(jeu)) !=0)
    {
        if(GetSpriteIron(GetIron(jeu)) <3)
        {
            decoupe.x = 40;
        }
        else
        {
            decoupe.x = 80;
            if(GetSpriteIron(GetIron(jeu)) == 5)
            {
                SetSpriteIron(GetIron(jeu),0);
            }
        }
        SetSpriteIron(GetIron(jeu),GetSpriteIron(GetIron(jeu))+1);
    }

    MettreSurface(images->iron,images->ecran,X,GetYIron(GetIron(jeu)),&decoupe);

    if(GetVapeur(GetIron(jeu)) >0)
    {
        if(GetXIron(GetIron(jeu)) < 320)
        {
            Xvapeur = GetVapeurX(GetIron(jeu));
        }
        else if(GetXIron(GetIron(jeu)) > approcheFinNiveau)
        {
            Xvapeur = GetVapeurX(GetIron(jeu))-(approcheFinNiveau-320);
        }
        else
        {
            Xvapeur = GetVapeurX(GetIron(jeu))-GetXIron(GetIron(jeu)) + 320;
        }

        alpha = GetVapeur(GetIron(jeu))*5;
        SDL_SetAlpha(images->vapeur, SDL_SRCALPHA | SDL_RLEACCEL, alpha );
        MettreSurface(images->vapeur,images->ecran,Xvapeur,GetVapeurY(GetIron(jeu)),NULL);
    }

    decoupe.x = decoupe.y = 0;

    for(i=0 ; i<GetVieIron(GetIron(jeu)) ; i++)
    {
        MettreSurface(images->iron,images->ecran,Xvie,455,&decoupe);
        Xvie = Xvie + 6;
    }
}


        /*  FONCTIONS CONCERNANT LES ENNEMIS */

void AfficherLesEnnemisSDL(IMAGE *images, const JEU *jeu)
{
    CASEENNEMI * parcours = GetAdressePremCase(GetListe(jeu));
	ENNEMI * temp;

	while (parcours != NULL)        /*  parcours des ennemis pour savoir lesquels sont sur l'ecran */
	{
		temp=GetAdresseEnnemiCase(parcours);
		if (EstSurEcranEnnemi(jeu,temp))
		{
            AfficherEnnemiSDL(images,parcours,jeu);     /*  si c'est le cas on l'affiche */
		}
		parcours=GetCaseSuivante(parcours);
	}
}

void AfficherEnnemiBoule(IMAGE *images,ENNEMI * ennemi, SDL_Rect *decoupe)
{
    if(GetSpriteEnnemi(ennemi) >= 0)
    {
        if(GetCompteurEnnemi(ennemi) > 2)
        {
            if(GetVitesseXEnnemi(ennemi) < 0)
            {
                SetSpriteEnnemi(ennemi,GetSpriteEnnemi(ennemi)+1);
                if(GetSpriteEnnemi(ennemi)>3)
                {
                    SetSpriteEnnemi(ennemi,0);
                }
            }
            else
            {
                SetSpriteEnnemi(ennemi,GetSpriteEnnemi(ennemi)-1);
                if(GetSpriteEnnemi(ennemi)<0)
                {
                    SetSpriteEnnemi(ennemi,3);
                }
            }
            SetCompteurEnnemi(ennemi,0);
        }


        decoupe->x = GetSpriteEnnemi(ennemi) * 20;
    }
    else
    {
        decoupe->y = 20;
        if(GetCompteurEnnemi(ennemi) > 10)
        {
            SetSpriteEnnemi(ennemi, GetSpriteEnnemi(ennemi) - 1);
            SetCompteurEnnemi(ennemi,0);
        }
        decoupe->x = -((GetSpriteEnnemi(ennemi) + 1) * 20);
    }

    SetCompteurEnnemi(ennemi, GetCompteurEnnemi(ennemi) + 1);
}

void AfficherEnnemiBouleDeNeige(IMAGE *images,ENNEMI * ennemi, SDL_Rect *decoupe)
{
    if(GetSpriteEnnemi(ennemi) >= 0)
    {
        if(GetCompteurEnnemi(ennemi) > 2)
        {
            if(GetVitesseXEnnemi(ennemi) < 0)
            {
                SetSpriteEnnemi(ennemi,GetSpriteEnnemi(ennemi)+1);
                if(GetSpriteEnnemi(ennemi)>3)
                {
                    SetSpriteEnnemi(ennemi,0);
                }
            }
            else
            {
                SetSpriteEnnemi(ennemi,GetSpriteEnnemi(ennemi)-1);
                if(GetSpriteEnnemi(ennemi)<0)
                {
                    SetSpriteEnnemi(ennemi,3);
                }
            }
            SetCompteurEnnemi(ennemi,0);
        }

        decoupe->x = GetSpriteEnnemi(ennemi) * 20;
    }
    else
    {
        decoupe->y = 20;
        if(GetCompteurEnnemi(ennemi) > 10)
        {
            SetSpriteEnnemi(ennemi, GetSpriteEnnemi(ennemi) - 1);
            SetCompteurEnnemi(ennemi,0);
        }

        decoupe->x = -((GetSpriteEnnemi(ennemi) + 1) * 20);

    }

    SetCompteurEnnemi(ennemi, GetCompteurEnnemi(ennemi) + 1);
}

void AfficherEnnemiTombant(IMAGE *images,ENNEMI *ennemi, SDL_Rect *decoupe)
{
    if(GetSpriteEnnemi(ennemi) == -1)
    {
        decoupe->x = 20;
    }
    else if(GetSpriteEnnemi(ennemi) < -1)
    {
        decoupe->y = 20;

        if(GetCompteurEnnemi(ennemi) > 10)
        {
            SetSpriteEnnemi(ennemi, GetSpriteEnnemi(ennemi) - 1);
            SetCompteurEnnemi(ennemi,0);
        }

        decoupe->x = -((GetSpriteEnnemi(ennemi) + 2) * 20);
    }

    SetCompteurEnnemi(ennemi, GetCompteurEnnemi(ennemi) + 1);
}

void AfficherEnnemiSDL(IMAGE *images,CASEENNEMI *ennemi, const JEU *jeu)
{
    SDL_Surface * Im;
    SDL_Rect decoupe;

    int positionXEnnemi;
    int approcheFinNiveau;

    decoupe.x = decoupe.y = 0;
    decoupe.h = decoupe.w = 20;

    approcheFinNiveau = GetDimXNiveau(GetTerrain(jeu))*GetDimensionCaseNiveau(GetTerrain(jeu)) - 16*GetDimensionCaseNiveau(GetTerrain(jeu));
    /*  switch en fonction du type pour savoir quel ennemi afficher */
    switch(GetTypeEnnemi(GetAdresseEnnemiCase(ennemi)))
    {
        case '1' :
            Im = images->ennemiTombant;

            AfficherEnnemiTombant(images, GetAdresseEnnemiCase(ennemi), &decoupe);

            break;
        case '2' :
            Im = images->ennemiBoule;

            AfficherEnnemiBoule(images,GetAdresseEnnemiCase(ennemi), &decoupe);

            break;

        case '3' :
            Im = images->ennemiBouleDeNeige;

            AfficherEnnemiBouleDeNeige(images,GetAdresseEnnemiCase(ennemi), &decoupe);

            break;
        case '4' :
            Im = images->ennemiCanon;

            if(GetVitesseXEnnemi(GetAdresseEnnemiCase(ennemi)) < 0)
            {
                decoupe.x = 20;
            }
            break;

        case '7' :
            Im = images->boss;
            decoupe.w = decoupe.h = 80;

            break;

        case '8' :
            Im = images->ennemiBouleDeNeige;

            AfficherEnnemiBouleDeNeige(images,GetAdresseEnnemiCase(ennemi), &decoupe);

            break;

        default :
            break;
    }


    if(GetXIron(GetIron(jeu)) < 320)
    {
        positionXEnnemi = GetXEnnemi(GetAdresseEnnemiCase(ennemi));
    }
    else if(GetXIron(GetIron(jeu)) > approcheFinNiveau)
    {
        positionXEnnemi = GetXEnnemi(GetAdresseEnnemiCase(ennemi))-(approcheFinNiveau-320);
    }
    else
    {
        positionXEnnemi = GetXEnnemi(GetAdresseEnnemiCase(ennemi))-GetXIron(GetIron(jeu)) + 320;
    }


    MettreSurface(Im,images->ecran,positionXEnnemi,GetYEnnemi(GetAdresseEnnemiCase(ennemi)),&decoupe);

}


		/*	FONCTIONS GENERALE */

void MettreSurface(SDL_Surface *surfaceAMettre, SDL_Surface *surfaceSupport, const int x, const int y, SDL_Rect *partieImage)
{
    SDL_Rect position;
    position.x = x;
    position.y = y;

    SDL_BlitSurface(surfaceAMettre,partieImage, surfaceSupport, &position);
}



